﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Data.Common;
using System.Xml;
using System.ComponentModel;
using MacomberMapSystem.Common.Serialization;
using MacomberMapSystem.Common.User_Interfaces;
using System.Drawing;

namespace MacomberMapSystem.Common.Integration
{
    /// <summary>
    /// Store display information on a particular KV level
    /// </summary>
    public class MM_KVLevel : MM_Serializable, IComparable
    {
        #region Variable declarations

        /// <summary>The display parameters for energized state</summary>        
        public MM_Display_Parameter Energized;

        /// <summary>The display parameters for energized state</summary>
        public MM_Display_Parameter PartiallyEnergized;

        /// <summary>The display parameters for deenergized state</summary>
        public MM_Display_Parameter DeEnergized;

        /// <summary>The name of the voltage level</summary>
        public String Name;

        private bool _ShowEnergized, _ShowPartiallyEnergized, _ShowDeEnergized, _ShowMVA, _Permitted;
        private bool _ShowMWText, _ShowMVARText, _ShowMVAText, _ShowPercentageText;
        private float _MVAThreshold, _MVASize = 7f;

        /// <summary>
        /// Whether this KV level is permitted to be displayed in the network map
        /// </summary>
        [Category(" Visibility"), Description("Whether this KV level is permitted to be displayed in the network map"), DefaultValue(true)]
        public bool Permitted
        {
            get { return _Permitted; }
            set { _Permitted = value; }
        }


        /// <summary>
        /// Show energized lines in the network map
        /// </summary>
        [Category(" Visibility"), Description("Show energized lines in the network map"), DefaultValue(true)]
        public bool ShowEnergized
        {
            get { return _ShowEnergized; }
            set { _ShowEnergized = value; }
        }

        /// <summary>
        /// Show partially energized lines in the network map
        /// </summary>
        [Category(" Visibility"), Description("Show partially energized lines in the network map"), DefaultValue(true)]
        public bool ShowPartiallyEnergized
        {
            get { return _ShowPartiallyEnergized; }
            set { _ShowPartiallyEnergized = value; }
        }

        /// <summary>
        /// Show de-energized lines in the network map
        /// </summary>
        [Category(" Visibility"), Description("Show de-energized lines in the network map"), DefaultValue(true)]
        public bool ShowDeEnergized
        {
            get { return _ShowDeEnergized; }
            set { _ShowDeEnergized = value; }
        }


        /// <summary>
        /// Show the overall visibility of this KV level
        /// </summary>
        [Category(" Visibility"), Description("Show the overall visibility of this KV level"), DefaultValue(true), ReadOnly(true)]
        public bool SimpleVisibility
        {
            get { return _ShowEnergized | _ShowDeEnergized | _ShowPartiallyEnergized; }
            set { _ShowEnergized = _ShowDeEnergized = _ShowPartiallyEnergized = value; }
        }

        /// <summary>
        /// Show MVA flow in the network map
        /// </summary>
        [Category("MVA Animation"), Description("Show MVA flow in the network map"), DefaultValue(false)]
        public bool ShowMVA
        {
            get { return _ShowMVA; }
            set { _ShowMVA = value; }
        }

        /// <summary>
        /// The threshold (in percent) at or over which the MVA flow should be shown
        /// </summary>
        [Category("MVA Animation"), Description("The threshold (in percent) at or over which the MVA flow should be shown"), DefaultValue(0f)]
        public float MVAThreshold
        {
            get { return _MVAThreshold; }
            set { _MVAThreshold = value; }
        }


        /// <summary>
        /// The base size of an MVA flow line at 100% of normal limit
        /// </summary>
        [Category("MVA Animation"), Description("The base size of an MVA flow line at 100% of normal limit")]
        public float MVASize
        {
            get { return _MVASize; }
            set { _MVASize = value; }
        }



        /// <summary>
        /// Whether the MW flow and direction should be displayed above the line
        /// </summary>
        [Category("Status text"), Description("Whether the MW flow and direction should be displayed above the line"), DefaultValue(false)]
        public bool ShowMWText
        {
            get { return _ShowMWText; }
            set { _ShowMWText = value; }
        }


        /// <summary>
        /// Whether the MVAR flow and direction should be displayed above the line
        /// </summary>
        [Category("Status text"), Description("Whether the MVAR flow and direction should be displayed above the line"), DefaultValue(false)]
        public bool ShowMVARText
        {
            get { return _ShowMVARText; }
            set { _ShowMVARText = value; }
        }

        /// <summary>
        /// Whether the MVA flow and direction should be displayed above the line
        /// </summary>
        [Category("Status text"), Description("Whether the MVA flow and direction should be displayed above the line"), DefaultValue(false)]
        public bool ShowMVAText
        {
            get { return _ShowMVAText; }
            set { _ShowMVAText = value; }
        }

        /// <summary>
        /// Whether the Percentage flow and direction should be displayed above the line
        /// </summary>
        [Category("Status text"), Description("Whether the percentage of MVA flow and direction should be displayed above the line"), DefaultValue(false)]
        public bool ShowPercentageText
        {
            get { return _ShowPercentageText; }
            set { _ShowPercentageText = value; }
        }
        #endregion

        #region Initialization
        /// <summary>
        /// Initialize a new KV Level
        /// </summary>
        /// <param name="ElementSource">Our element source</param>
        /// <param name="Repository">The data repository</param>
        public MM_KVLevel(XmlElement ElementSource,MM_Repository Repository)
            : base(ElementSource,Repository)
        {
            this.Energized = new MM_Display_Parameter(ElementSource["Energized"], Repository);
            this.PartiallyEnergized = new MM_Display_Parameter(ElementSource["PartiallyEnergized"], Repository);
            this.DeEnergized = new MM_Display_Parameter(ElementSource["DeEnergized"],Repository);
        }

        /// <summary>
        /// Initialize a new KV level based on its name and foreground color
        /// </summary>
        /// <param name="Name">The name of the KV level</param>
        /// <param name="ForeColor">The foreground color </param>
        /// <param name="Repository">The repository that may contain additionally needed elements</param>
        public MM_KVLevel(String Name, String ForeColor, MM_Repository Repository): base(null,Repository)
        {
            this.Name = Name;
            this.Energized = new MM_Display_Parameter(ColorTranslator.FromHtml(ForeColor), 1, false, Repository);
            this.DeEnergized = new MM_Display_Parameter(Color.DarkGray, 1, false, Repository);
            this.PartiallyEnergized = new MM_Display_Parameter(Color.DarkGray, 1, false, Repository);
            this.ID = Data_Manager.KVLevels.Count;
        }

        /// <summary>
        /// Initialize a new KV level from a database
        /// </summary>
        /// <param name="DataReader"></param>
        /// <param name="Repository">The data repository</param>
        public MM_KVLevel(DbDataReader DataReader, MM_Repository Repository)
            : base(DataReader, null, Repository)
        {
            this.Name = Convert.ToString(DataReader["Name"]);
            this.Energized = new MM_Display_Parameter(Color.FromArgb(Convert.ToInt32(DataReader["Energized.ForeColor"])), Convert.ToInt32(DataReader["Energized.Thickness"]), Convert.ToInt32(DataReader["Energized.Blink"]) != 0, Repository);
            this.DeEnergized = new MM_Display_Parameter(Color.FromArgb(Convert.ToInt32(DataReader["DeEnergized.ForeColor"])), Convert.ToInt32(DataReader["DeEnergized.Thickness"]), Convert.ToInt32(DataReader["DeEnergized.Blink"]) != 0, Repository);
            this.PartiallyEnergized = new MM_Display_Parameter(Color.FromArgb(Convert.ToInt32(DataReader["PartiallyEnergized.ForeColor"])), Convert.ToInt32(DataReader["PartiallyEnergized.Thickness"]), Convert.ToInt32(DataReader["PartiallyEnergized.Blink"]) != 0, Repository);
            this.ID = Convert.ToInt32(DataReader["ID"]);
        }

        /// <summary>
        /// Update the KV level, and its underlying components
        /// </summary>
        /// <param name="ElementSource">The XML source of the element</param>
        /// <param name="Repository">The repository that may contain additionally needed elements</param>
        public void ReadXML(XmlElement ElementSource, MM_Repository Repository)
        {
            MM_Serializable.InitializeFromXml(Energized, ElementSource["Energized"], Repository);
            MM_Serializable.InitializeFromXml(PartiallyEnergized, ElementSource["PartiallyEnergized"], Repository);
            MM_Serializable.InitializeFromXml(DeEnergized, ElementSource["DeEnergized"], Repository);
            MM_Serializable.InitializeFromXml(this, ElementSource, Repository);            
        }

        /*/// <summary>
        /// Initialize a new KV Level display
        /// </summary>
        /// <param name="xE"></param>
        public MM_KVLevel(XmlElement xE)
        {
            this.Name = xE.Attributes["Name"].Value;
            

            ReinitializeDisplay(xE);
        }

        /// <summary>
        /// Reinitialize the display elements
        /// </summary>
        /// <param name="xE"></param>
        public void ReinitializeDisplay(XmlElement xE)
        {
            this.Energized.ReinitializeDisplay(xE["Energized"]);
            this.PartiallyEnergized.ReinitializeDisplay(xE["PartiallyEnergized"]);
            this.DeEnergized.ReinitializeDisplay(xE["DeEnergized"]);

            if (xE.HasAttribute("ShowPartiallyEnergized"))
                this.ShowPartiallyEnergized = XmlConvert.ToBoolean(xE.Attributes["ShowPartiallyEnergized"].Value);
            if (xE.HasAttribute("ShowEnergized"))
                this.ShowEnergized = XmlConvert.ToBoolean(xE.Attributes["ShowEnergized"].Value);
            if (xE.HasAttribute("Permitted"))
                this.Permitted = XmlConvert.ToBoolean(xE.Attributes["Permitted"].Value);            
            if (xE.HasAttribute("ShowDeEnergized"))
                this.ShowDeEnergized = XmlConvert.ToBoolean(xE.Attributes["ShowDeEnergized"].Value);            
            if (xE.HasAttribute("ShowMW"))
                this.ShowMVA= XmlConvert.ToBoolean(xE.Attributes["ShowMW"].Value);
            if (xE.HasAttribute("ShowMVA"))
                this.ShowMVA = XmlConvert.ToBoolean(xE.Attributes["ShowMVA"].Value);
            if (xE.HasAttribute("MVAThreshold"))
                this.MVAThreshold = MM_Converter.ToSingle(xE.Attributes["MVAThreshold"].Value);
            if (xE.HasAttribute("MWThreshold"))
                this.MVAThreshold = MM_Converter.ToSingle(xE.Attributes["MWThreshold"].Value);
            if (xE.HasAttribute("MVASize"))
                this.MVASize = MM_Converter.ToSingle(xE.Attributes["MVASize"].Value);
            
        }*/
        #endregion

        #region IComparable Members
        /// <summary>
        /// Handle the comparison between KV levels to allow for sorting
        /// </summary>
        /// <param name="obj"></param>
        /// <returns></returns>
        public int CompareTo(object obj)
        {
            int CurVal = 0, OtherVal = 0;
            int.TryParse(Name.Split(' ')[0], out CurVal);
            int.TryParse((obj as MM_KVLevel).Name.Split(' ')[0], out OtherVal);
            return OtherVal.CompareTo(CurVal);
        }

        #endregion


        /// <summary>
        /// Display the name of the KV level
        /// </summary>
        /// <returns></returns>
        public override string ToString()
        {
            return this.Name;
        }
    }

}
